// get 方法是 JavaScript 中定义访问器属性的一种方式。它允许你为对象属性定义一个 getter，从而使得你可以在访问该属性时执行一个函数逻辑，
// 而不是直接访问其值。通过 get 方法，你可以对属性进行控制和计算，但对外部用户来说，它就像是一个普通的属性一样可以访问。

// get 方法的语法
// javascript
// 复制代码
// const obj = {
//   get propertyName() {
//     // 返回值可以是计算得来的
//     return 'some value';
//   }
// };

// console.log(obj.propertyName);  // 输出 'some value'



//这里只写 原理 需要配合 官方 vue 包来进行验证====
export let Vue
// 类 也就是Store构造函数 用来创建store实例
export class Store {
    constructor(options) {
        // options是用户 配置写的 Store实例的时候 传入的配置项信息。
        this.mutations = options.mutations || {}
        // debugger



        // 2.0实现mutations的执行---store实例添加一个commit方法来  执行mutaitions中定义的 方法。然后默认第一个参数是state,第二个参数hi是用户传入的参数 
        this.commit = (type, payload) => {
            // 实现mutations的执行 默认第一个参数是当前store实例的 state数据 第二个参数是用户传入的参数
            this.mutations[type](this.state, payload)
        }
        //3.0 实现getters
        let oldGetters = options.getters || {}; // 用户写的getters方法
        this.getters = {}; //界面需要调用的getters==》》 this  === new Store()实例 == $store
        // 3.1 实现getters的响应式
        //3.2 实现getters的缓存机制---利用vue中的computed来实现
        var computed = {}; 
        Object.keys(oldGetters).forEach(key => {
            computed[key] = () => {
                return oldGetters[key](this.state) // 在这里调用 getters中的方法 传入state数据
            }
            Object.defineProperty(this.getters, key, {
                get: () => {
                    console.log(this._vm, 'this._vm')
                    return this._vm && this._vm[key]
                }
            })
        })




        //Vuex都是利用 Vue实例中的 属性或者方法来实现的 1.0实现state的响应式使用data属性
        this._vm = new Vue({
            data() {
                return {
                    state: options.state || {}
                }
            },
            computed
        })



    }
    // 实现  添加一个state属性 用来获取state数据 $store.state.age
    get state() {
        return this._vm.state
    }

}

//想给每一个组件 都添加一个公共的方法 那么就用Vue.mixin({}) 实现 store 放到每一个使用的组件中
export const install = function (_Vue) {
    Vue = _Vue
    // 使用Vue 提供的方法 Vue.mixin({})混入方法  数据 
    // 通过Vue实例上的方法 Vue.mixin({}) 来实现 store 对象 和每一个组件的关联
    Vue.mixin({
        beforeCreate() {
            console.log(this, this.$options.name, 'install-Vue-this-beforeCreate')
            // 只有根实例才会创建 store,将store 放到每一个组件中
            if (this.$options.store) {
                // 根实例组件
                Vue.prototype.$store = this.$options.store
            } else {
                // 子组件---通过$parent 获取父组件的 store
                Vue.prototype.$store = this.$parent && this.$parent.$store
            }
        },
        created() {
            console.log(this, 'install-Vue-this-created')
        },
        beforeMount() {
            console.log(this, 'install-Vue-this-beforeMount')
        },
        mounted() {
            console.log(this, 'install-Vue-this-mounted')
        }
    })
}